package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.InstockProductDao;
import com.xbongbong.saas.domain.entity.BusinessProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.ext.InstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.util.StandardizeDataUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author Jian.Wang
 * @date  2019-02-21 15:38
 **/
@Service("InstockProductModel")
public class InstockProductModelImpl implements InstockProductModel {

    @Resource
    private InstockProductDao instockProductDao;
    @Resource
    private ProductModel productModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private InstockModel instockModel;

    /**
     * 入库单产品数据插入
     *
     * @param instockProductEntity 供应商实体
     * @return Integer
     * @throws XbbException 异常
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer insert(InstockProductEntity instockProductEntity) throws XbbException {
        instockProductEntity.setAddTime(DateTimeUtil.getInt());
        instockProductEntity.setUpdateTime(DateTimeUtil.getInt());
        StandardizeDataUtil.standardizeNotString(instockProductEntity);
        return instockProductDao.insert(instockProductEntity);
    }

    /**
     * 入库单产品数据更新
     *
     * @param instockProductEntity 供应商实体
     * @return Integer
     * @throws XbbException 异常
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer update(InstockProductEntity instockProductEntity) throws XbbException {
        instockProductEntity.setUpdateTime(DateTimeUtil.getInt());
        StandardizeDataUtil.standardizeNotString(instockProductEntity);
        return instockProductDao.update(instockProductEntity);
    }

    /**
     * 入库单产品数据保存
     *
     * @param instockProductEntity 供应商实体
     * @return Integer
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer save(InstockProductEntity instockProductEntity) throws XbbException {
        Long id = instockProductEntity.getId();
        if (id == null || Objects.equals(id, 0L)) {
            return insert(instockProductEntity);
        }
        return update(instockProductEntity);
    }

    /**
     * 入库单产品数据删除
     *
     * @param key    要删除的Id
     * @param corpid 公司ID
     * @return Integer
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer deleteByKey(Long key, String corpid) {
        return instockProductDao.deleteByKey(key, corpid);
    }

    /**
     * 根据入库单Id删除所有入库单产品
     *
     * @param intoWarehouseId 入库ID
     * @param corpid          公司ID
     * @return Integer
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer deleteByInstockId(Long intoWarehouseId, String corpid) {
        return null;
    }

    /**
     * 根据入库单Id删除所有入库单产品--批量
     *
     * @param corpid      公司ID
     * @param instockIdIn 入库单Id集合
     * @return Integer
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer deleteByInstockIdIn(String corpid, List<Long> instockIdIn) {
        return instockProductDao.deleteByInstockIdIn(corpid, instockIdIn);
    }

    /**
     * 根据入库单Id删除所有入库单产品--批量
     *
     * @param key    数据ID
     * @param corpid 公司ID
     * @return InstockProductEntity
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public InstockProductEntity getByKey(Long key, String corpid) {
        return instockProductDao.getByKey(key, corpid);
    }

    @Override
    public List<InstockProductEntity> getProductsByInstockIdIn(String corpid, List<Long> instockIdIn) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("instockIdIn", instockIdIn);
        param.put("del", 0);
        param.put(ParameterConstant.ORDER_BY_STR, StringConstant.SAAS_LINK_BUSINESS_ID);
        return instockProductDao.findEntitys(param);
    }

    @Override
    public List<InstockProductEntity> getProductsByInstockIdAndType(String corpid, List<Long> instockIdIn, Integer type) {
        if (CollectionsUtil.isEmpty(instockIdIn)) {
            return new ArrayList<>();
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("intoWarehouseIdIn", instockIdIn);
        param.put("type", type);
        param.put(ParameterConstant.DEL, 0);
        return instockProductDao.findEntitys(param);
    }

    @Override
    public List<InstockProductEntity> getProductsByInstockIdIn(String corpid, Long instockId, List<Integer> delIn) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("intoWarehouseId", instockId);
        param.put("delIn", delIn);
        param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
        return instockProductDao.findEntitys(param);
    }

    /**
     * 入库单产品数据查询多个
     *
     * @param param 参数
     * @return List
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public List<InstockProductEntity> findEntitys(Map<String, Object> param) {
        return instockProductDao.findEntitys(param);
    }

    /**
     * 入库单产品数据查询条数
     *
     * @param param 参数
     * @return Integer
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return instockProductDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    /**
     * 更新仓库产品数据  包括库存和成本
     *
     * @param corpid          公司ID
     * @param warehouseId     仓库Id
     * @param instockProducts 入库产品集合
     * @author GuoJun.HU
     * 创建时间： 2017/3/29 14:36
     */
    @Override
    public String updateWarehouseProduct(String corpid, Long warehouseId, List<InstockProductEntity> instockProducts) {
        if (instockProducts.isEmpty()) {
            return "";
        }
        List<Long> productIds = new ArrayList<>();
        instockProducts.forEach(instockProductEntity -> productIds.add(instockProductEntity.getProductId()));
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        return null;
    }

    /**
     * 入库单导入时导入关联产品
     *
     * @param instock 入库单
     * @author GuoJun.HU
     * @since 3.27
     * 创建时间 2018/8/9 15:38
     */
    @Override
    public void setInstockProduct(InstockEntityExt instock) {

    }

    @Override
    public InstockProductEntity setLatestParam(InstockProductEntity instockProduct, List<ProductEntityExt> products) {
        Integer sort = 0;
        for (ProductEntityExt product : products) {
            if (instockProduct.getProductId().equals(product.getId())) {
                JSONObject productData = product.getData();
                String specification = productData.getString(ProductEnum.SPECIFICATION.getAttr());
                String productName = productData.getString(ProductEnum.NAME.getAttr());
                String unit = productData.getString(ProductEnum.UNIT.getAttr());

                ProductEntityExt parentProduct = productModel.getByKey(product.getId(), product.getCorpid());
                instockProduct.setProductSpecification(StringUtil.isEmpty(specification) ? "{}" : specification);
                instockProduct.setProductName(StringUtil.isEmpty(productName) ? "" : productName);
                instockProduct.setProductUnit(StringUtil.isEmpty(unit) ? "" : unit);

                JSONObject jsonObject = parentProduct.getData();
                String productNo = jsonObject.getString(ProductEnum.PRODUCT_NO.getAttr());

                instockProduct.setProductNo(StringUtil.isEmpty(productNo) ? "" : productNo);
                instockProduct.setSort(sort);
                sort++;
            }
        }
        return instockProduct;
    }

    /**
     * 保存产品扩展字段
     *
     * @param productObj     产品json对象
     * @param nowTemplateId  产品库存模板id
     * @param instockProduct 入库单产品
     * @author 周智
     * 创建时间： 2017-12-7 11:28
     */
    @Override
    public void saveRedundantField(JSONObject productObj, Long nowTemplateId, InstockProductEntity instockProduct) {

    }

    /**
     * 获取入库单关联产品的库存产品信息
     *
     * @param corpid           公司id
     * @param relativeProducts 入库单产品
     * @return 入库单产品库存信息
     * @author GuoJun.HU
     * 创建时间：2017/12/5 9:22
     */
    @Override
    public Map<Long, List<InstockProductEntity>> setInstockProductExtraInfo(String corpid, List<InstockProductEntity> relativeProducts) {
        return null;
    }

    /**
     * @param corpid       公司id
     * @param nameOrNoLike 产品名称或编号
     * @description 通过产品名称或编号查询对应的入库单id
     */
    @Override
    public List<Long> findInstockIdsByRelaProNameOrNo(String corpid, String nameOrNoLike) {
        return null;
    }

    /**
     * 对于可以分批入库的单据，某些场景需要将多次入库的同一个产数量合并
     *
     * @param instockProductList@author GuoJun.HU
     * @return 创建时间 2018/9/6 20:07
     * @since 3.27
     */
    @Override
    public Collection<InstockProductEntity> mergeInstockProduct(List<InstockProductEntity> instockProductList) {
        return null;
    }

    /**
     * 入库产品实体List
     *
     * @param param 包含产品IdList
     * @return 入库产品实体，包含产品Id和成品入库总成本
     * @author 徐俊杰
     * @since 汪汪十一月
     * 创建时间 2018/12/20 17:20
     * 修改时间
     */
    @Override
    public List<InstockProductEntity> getCostSum(Map<String, Object> param) {
        return instockProductDao.getCostSum(param);
    }

    @Override
    public Double getProductNumSum(Map<String, Object> param) {
        return instockProductDao.getProductNumSum(param);
    }

    @Override
    public Integer deleteBatchById(Collection<Long> delInstockProductIdList, String corpid, Integer del) {
        return instockProductDao.deleteBatchById(delInstockProductIdList,corpid, del);
    }

    @Override
    public void insertBatch(List<InstockProductEntity> instockProductEntityList) {
        StandardizeDataUtil.standardize4InstockProductEntityList(instockProductEntityList);
        instockProductDao.insertBatch(instockProductEntityList);
    }

    @Override
    public List<InstockProductEntity> sumProductNumGroupProAndWarehouse(List<Long> dataIdList, String corpid) {
        return instockProductDao.sumProductNumGroupProAndWarehouse(dataIdList, corpid);
    }

    @Override
    public List<BusinessProductEntity> findProductNum(Map<String, Object> param) {
        return instockProductDao.findProductNum(param);
    }

    @Override
    public Integer findProductNumCount(Map<String, Object> param) {
        return instockProductDao.findProductNumCount(param);
    }

    /**
     * @Description:
     * @Param: [corpid, warehouseIdIn, del]
     * @return: java.util.Map<java.lang.Long, com.xbongbong.saas.domain.entity.InstockProductEntity>
     * @Author: cyy
     * @Date: 2019/11/11
     */
    @Override
    public Map<Long, InstockProductEntity> getInstockProductMapByIdIn(String corpid, List<Long> warehouseIdIn, Integer del) {
//        List<InstockProductEntity> instockProductEntity = getProductListByIdIn(corpid, productIdIn, del);
//        Map<Long, ProductEntityExt> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        for (ProductEntityExt product : productList) {
//            productMap.put(product.getId(), product);
//        }
//        return productMap;
        return null;
    }

    @Override
    public Integer updateBatch(List<InstockProductEntity> updateList, String corpid) throws XbbException {
        StandardizeDataUtil.standardize4InstockProductEntityList(updateList);
        return instockProductDao.updateBatch(updateList, corpid);
    }

    @Override
    public Long isProductSubAttrExist(String attr, String corpid, Long formId, Integer isArray) {
        return instockProductDao.isProductSubAttrExist(attr, corpid, formId, isArray);
    }

    @Override
    public List<InstockProductEntity> getUpStreamProduct(String corpid, Integer type, Long refId) throws XbbException {
        // 是否开启了工作流
        boolean isOpenWorkflow = commonHelp.isOpenWorkFlow(corpid);
        if (!isOpenWorkflow) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("refId", refId);
            param.put("type", type);
            param.put("del", 0);
            param.put("orderByStr", "sort");
            return findEntitys(param);
        } else {
            List<PaasFormDataEntityExt> instockList = instockModel.findInstockList(corpid, type, refId,
                    Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType()), Arrays.asList(FieldTypeEnum.DATAID.getAlias()));
            List<Long> instockIdIn = new ArrayList<>();
            instockList.forEach(item -> instockIdIn.add(item.getDataId()));

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("refId", refId);
            param.put("type", type);
            param.put("del", 0);
            param.put("orderByStr", "sort");
            param.put("intoWarehouseIdIn", instockIdIn);
            return findEntitys(param);
        }
    }

    @Override
    public InstockProductEntity getProductsByInstockIdAndRefProductId(Long instockId, Long refProductId, String corpid) {
        return instockProductDao.getProductsByInstockIdAndRefProductId(instockId, refProductId, corpid);
    }

    @Override
    public Double summaryByAttr(String field, String corpid, Long refId, List<Long> productIdIn) {
        return instockProductDao.summaryByAttr(field, corpid, refId, productIdIn);
    }

    @Override
    public Double summaryByAttrFromOutSide(String field, String corpid, Long refId, List<Long> productIdIn) {
        return instockProductDao.summaryByAttrFromOutSide(field, corpid, refId, productIdIn);
    }


    @Override
    public Integer dataConsistencyUpdate(String corpid, Long productId, String productName, String specification, String productNo) {
        return instockProductDao.dataConsistencyUpdate(corpid, productId, productName, specification, productNo);
    }

    @Override
    public Long countProductSub(String attr, String corpid, Long formId, Integer isArray) {
        return instockProductDao.countProductSub(attr, corpid, formId, isArray);
    }

    @Override
    public List<InstockProductEntity> getProductWithSubData(String attr, String corpid, Long formId, Integer isArray, Long idGte, Integer limit) {
        return instockProductDao.getProductWithSubData(attr, corpid, formId, isArray, idGte, limit);
    }


    @Override
    public Integer updateMulti(List<InstockProductEntity> list, String corpid) throws XbbException {
        StandardizeDataUtil.standardize4InstockProductEntityList(list);
        return instockProductDao.updateMulti(list, corpid);
    }

    @Override
    public List<InstockProductEntity> findRefundkProductandContract(Map<Long, Long> stockAndRefund, String corpid) {
        return instockProductDao.findRefundkProductandContract(stockAndRefund, corpid);
    }

    @Override
    public void updateInstockProductById(List<InstockProductEntity> instockProductEntityList, String corpid){
        StandardizeDataUtil.standardize4InstockProductEntityList(instockProductEntityList);
        instockProductDao.updateInstockProductById(instockProductEntityList, corpid);
    }

    @Override
    public List<InstockProductEntity> getInstockProductById(List<Long> instockProductId, String corpid ){
        return instockProductDao.getInstockProductById(instockProductId, corpid);
    }

    @Override
    public InstockProductEntity getInstockProductSum(Map<String, Object> map){
        return instockProductDao.getInstockProductSum(map);
    }

    @Override
    public List<InstockProductEntity> getInstockProductByRefId(Map<String, Object> param){
        return instockProductDao.getInstockProductByRefId(param);
    }

    @Override
    public Set<Long> getWarehouseIdUnion(Set<Long> warehouseIdList, String corpid) {
        if (CollectionsUtil.isEmpty(warehouseIdList)) {
            return new HashSet<>();
        }
        return instockProductDao.getWarehouseIdUnion(warehouseIdList, corpid);
    }
}
